#ifndef SANDBOX_SDK_MATH_VECTOR4I_HPP
#define SANDBOX_SDK_MATH_VECTOR4I_HPP
#include "vector4_details.h"
#include <type_traits>
namespace sandbox 
{
	namespace sdk
	{
		ALIGN_BEG(16) struct Vector4i {
			Vector4i(){}
			constexpr Vector4i(int a):value(_mm_set1_epi32(a)){}
			constexpr Vector4i(int x, int y, int z, int w):value(_mm_set_epi32(z,y,x,w)){}
			constexpr Vector4i(int x, int y, int z):value(_mm_set_epi32(z,y,x,0)){}
			
			Vector4i& operator +=(const Vector4i  x)	{value=_mm_add_epi32(value, x.value);return *this;}
			Vector4i& operator -=(const Vector4i  x)	{value=_mm_sub_epi32(value, x.value);return *this;}
			Vector4i& operator &=(const Vector4i  x)	{value=_mm_and_si128(value, x.value);return *this;}
			Vector4i& operator |=(const Vector4i  x)	{value=_mm_or_si128 (value, x.value);return *this;}
			Vector4i& operator ^=(const Vector4i  x)	{value=_mm_xor_si128(value, x.value);return *this;}
			Vector4i& nand       (const Vector4i  x)	{value=_mm_nand_si128(value, x.value);return *this;}
			Vector4i& nor        (const Vector4i  x)	{value=_mm_nor_si128(value, x.value);return *this;}
			Vector4i& operator <<=(int bits){value=_mm_slli_epi32(value, bits);return *this;}
			Vector4i& operator >>=(int bits){value=_mm_srli_epi32(value, bits);return *this;}
		
			Vector4f abs()const
			{return Vector4i(_mm_srli_epi32(_mm_slli_epi32(value,1),1));}
			template <int w, int x=w, int y=w, int z=w> Vector4i shuffle()const
			{return Vector4i(detail::shuffle<w,x,y,z>(value));}

			int mask()const{return _mm_movemask_ps(value);}
			enum { XMask(2), YMask(4), ZMask(8), WMask(1), XYZMask(0xE) }
			
			constexpr Vector4i(__m128i v):value(v){}
			__v4si value;
		} ALIGN_END(16);

		static_assert(std::is_pod<Vector4i>::value==true);
		static_assert(sizeof(Vector4i)==16);

		const Vector4i operator +(const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_add_epi32(a.value,b.value));}
		const Vector4i operator -(const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_sub_epi32(a.value,b.value));}

		const Vector4i operator &(const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_and_si128(a.value,b.value));}
		const Vector4i operator |(const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_or_si128(a.value,b.value));}
		const Vector4i operator ^(const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_xor_si128(a.value,b.value));}
		const Vector4i nand      (const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_nand_si128(a.value,b.value));}
		const Vector4i nor       (const Vector4i  a,const Vector4i  b)
		{return Vector4i(_mm_nor_si128(a.value,b.value));}
	}
}
#endif //SANDBOX_SDK_MATH_VECTOR4I_HPP
